/*
 * @Authoryour name
 * @Date2020-11-28 22:46:00
 * @LastEditTime2020-11-28 22:46:00
 * @LastEditorsyour name
 * @DescriptionIn User Settings Edit
 * @FilePath\STM32H750_FreeRTOS\User\schedule\schdule.c
 */ 
#include "schedule.h"
#include "backtrace.h"

TaskHandle_t task_handles[TASK_NUM];
StaticTask_t Idle_Task_TCB;
StackType_t Idle_Task_Stack[configMINIMAL_STACK_SIZE];
StaticTask_t Timer_Task_TCB;
StackType_t Timer_Task_Stack[configMINIMAL_STACK_SIZE];


void schedule_init(void)
{
    uint16_t index = 0;
    taskENTER_CRITICAL();
    for(index = 0; index < TASK_NUM; ++index)
    {
        task_handles[index] = xTaskCreateStatic((TaskFunction_t)task_infos[index].task_handler, 
                                                task_infos[index].task_name,
                                                task_infos[index].stack_depth,
                                                task_infos[index].para,
                                                task_infos[index].priority,
                                                task_infos[index].stack_buffer,
                                                task_infos[index].tcb);
    }
    taskEXIT_CRITICAL();
    vTaskStartScheduler();
}


/**
 * @description: Obtain the Idle Task TCB and Stack Address, Called by FreeRTOS
 * @param {StaticTask_t **} the Address that store the TCB Pointer
 * @param {StackType_t **} the Address that store the Stack Pointer
 * @param {uint32_t *} the Address that store the Stack Size
 * @return: void
 */
void vApplicationGetIdleTaskMemory(StaticTask_t **ppxIdleTaskTCBBuffer,
                                   StackType_t **ppxIdleTaskStackBuffer,
                                   uint32_t *pulIdleTaskStackSize)
{
    *ppxIdleTaskTCBBuffer = &Idle_Task_TCB;
    *ppxIdleTaskStackBuffer = Idle_Task_Stack;
    *pulIdleTaskStackSize = configMINIMAL_STACK_SIZE;
}

/**
 * @description: Obtain the Timer Task TCB and Stack Address, Called by FreeRTOS
 * @param {StaticTask_t **} the Address that store the TCB Pointer
 * @param {StackType_t **} the Address that store the Stack Pointer
 * @param {uint32_t *} the Address that store the Stack Size
 * @return: void
 */
void vApplicationGetTimerTaskMemory(StaticTask_t **ppxTimerTaskTCBBuffer,
                                    StackType_t **ppxTimerTaskStackBuffer,
                                    uint32_t *pulTimerTaskStackSize)
{
    *ppxTimerTaskTCBBuffer = &Timer_Task_TCB;
    *ppxTimerTaskStackBuffer = Timer_Task_Stack;
    *pulTimerTaskStackSize = configMINIMAL_STACK_SIZE;
}

task_info_t *schedule_find_task_info(uint32_t stack_addr)
{
    uint16_t index = 0;
    for(index = 0; index < TASK_NUM; ++index)
    {
        if(stack_addr == (uint32_t)task_infos[index].stack_buffer)
        {
            return (task_info_t *)(&task_infos[index]);
        }
    }
    return NULL;
}

/**
 * @brief  The systerm tick interrupt handler
 * @param  void
 * @retval void
 */
void SysTick_Handler(void)
{
    extern void xPortSysTickHandler();
#if (INCLUDE_xTaskGetSchedulerState == 1)
    if(xTaskGetSchedulerState() != taskSCHEDULER_NOT_STARTED)
    {
#endif
        xPortSysTickHandler();
#if (INCLUDE_xTaskGetSchedulerState == 1)
    }
#endif
}


/**
  * @brief  This function handles NMI exception.
  * @param  None
  * @retval None
  */
void NMI_Handler(void)
{
    /* Get the psp in the stack */
    while(1);
}

// /**
//   * @brief  This function handles Hard Fault exception.
//   * @param  None
//   * @retval None
//   */
// void HardFault_Handler(void)
// {
//     printf("Hard Fault!\r\n");
//     /* Go to infinite loop when Hard Fault exception occurs */
//     while (1)
//     {
//     }
// }

/**
  * @brief  This function handles Memory Manage exception.
  * @param  None
  * @retval None
  */
void MemManage_Handler(void)
{
    printf("Memory Manage Fault!\r\n");
    /* Go to infinite loop when Memory Manage exception occurs */
    while (1)
    {
    }
}

/**
  * @brief  This function handles Bus Fault exception.
  * @param  None
  * @retval None
  */
void BusFault_Handler(void)
{
    printf("Bus Fault!\r\n");
    /* Go to infinite loop when Bus Fault exception occurs */
    while (1)
    {
    }
}

/**
  * @brief  This function handles Usage Fault exception.
  * @param  None
  * @retval None
  */
void UsageFault_Handler(void)
{
    printf("Usage Fault!\r\n");
    /* Go to infinite loop when Usage Fault exception occurs */
    while (1)
    {
    }
}



